#import "sprite_game_bomb.h"

#define BOMB_STATE_MOVE 0
#define BOMB_STATE_DESTROY 1
#define BOMB_STATE_EXPLOSION 2

#define BOMB_TYPE_6_STATE_BIG 0
#define BOMB_TYPE_6_STATE_SMALL 1

@implementation SpriteGameBomb

@synthesize type = type_;
@synthesize attackPoint = attackPoint_;
@synthesize canBeDestroy = canBeDestroy_;
@synthesize flagTimeStopValid = flagTimeStopValid_;

- (id)initSpriteGameBomb:(int)Type
{
	if ((self = [super init]))
	{
		[self schedule:@selector(tick:)];

		type_ = Type;

		if (type_ != BOMB_TYPE_6)
		{
			attackPoint_ = g_CfgGameBombDataTable[Type].attack_point;
			canBeDestroy_ = g_CfgGameBombDataTable[Type].can_be_destroy;

			image_ = [[CCSprite alloc] initWithSpriteFrameName:[NSString stringWithUTF8String:g_CfgGameBombDataTable[Type].image_path]];
			[self addChild:image_];
			[image_ release];
			particle_ = nil;

			box2dBody_ = NULL;
			box2dFixture_ = NULL;
			[self CreateBody];

			state_ = BOMB_STATE_MOVE;
			flagTimeStopValid_ = false;
		}
		else
		{
			image_ = [CCSprite spriteWithFile:@"lightattack.png"];
			[self addChild:image_];
			imageLaserHead_ = [CCSprite spriteWithFile:@"lightattack_head.png"];
			[self addChild:imageLaserHead_];
			imageLaserHead_.anchorPoint = ccp(0.5, 0.0);
			imageLaserHead_.scaleY = 0.5;
		}
	}
	return self;
}

- (void)dealloc
{
	if (NULL != box2dBody_)
	{
		[g_LayerGameObject PutBox2dBodyToDestroyPool:box2dBody_];
		box2dBody_ = NULL;
		box2dFixture_ = NULL;
	}

	[super dealloc];
}

- (void)tick:(ccTime)Time
{
	if (NULL != box2dBody_)
	{
		box2dBody_->SetTransform([self ComputeBodyPosition], 0.0f);
	}

	if (type_ == BOMB_TYPE_6)
	{
		switch (flagBombType6State_)
		{
		case BOMB_TYPE_6_STATE_BIG:
			bombType6LineWidth_ += bombType6LineBigSegment_;
			imageLaserHead_.scaleX = image_.scaleX = bombType6LineWidth_ / image_.contentSizeInPixels.width;
			break;
		case BOMB_TYPE_6_STATE_SMALL:
			bombType6LineWidth_ -= bombType6LineSmallSegment_;
			imageLaserHead_.scaleX = image_.scaleX = bombType6LineWidth_ / image_.contentSizeInPixels.width;
			break;
		default:;
		}
	}
}

- (void)tickBombType6BigOver:(ccTime)Time
{
	[self unschedule:@selector(tickBombType6BigOver:)];
	[self schedule:@selector(tickBombType6SmallOver:) interval:bombType6SmallTime_];
	flagBombType6State_ = BOMB_TYPE_6_STATE_SMALL;
}

- (void)tickBombType6SmallOver:(ccTime)Time
{
	[self unschedule:@selector(tickBombType6SmallOver:)];
}

- (void)tickBombType6Over:(ccTime)Time
{
	[g_LayerGameObject RemoveBomb:self];
}

- (void)CreateBody
{
	int i;
	int _Count;
	b2BodyDef _BodyDef;
	b2PolygonShape _PolygonShape;
	b2FixtureDef _FixtureDef;
	b2Vec2 *_Vertex;

	_BodyDef.type = b2_dynamicBody;
	box2dBody_ = CMgrGamePhysics::World()->CreateBody(&_BodyDef);

	_Count = g_CfgGameBombDataTable[type_].box2d_collision_point_table.size();
	_Vertex = ptCreateCollisionVertex(&g_CfgGameBombDataTable[type_].box2d_collision_point_table);
	for (i = 0; i < _Count; ++i)
	{
		_Vertex[i] = ptScaleVector_same(_Vertex[i], 1 / CMgrGamePhysics::Ratio());
	}
	_PolygonShape.Set(_Vertex, _Count);
	free(_Vertex);

	_FixtureDef.shape = &_PolygonShape;
	_FixtureDef.density = 1.0f;
	_FixtureDef.isSensor = true;

	box2dFixture_ = box2dBody_->CreateFixture(&_FixtureDef);
}

- (void)DestroyBody
{
	if (NULL != box2dBody_)
	{
		[g_LayerGameObject PutBox2dBodyToDestroyPool:box2dBody_];
		box2dBody_ = NULL;
		box2dFixture_ = NULL;
	}
}

- (b2Vec2)ComputeBodyPosition
{
	return ptConvertCGPoint(ptScalePoint_same(self.positionInPixels, 1 / CMgrGamePhysics::Ratio()));
}

- (void)Pause
{
	[self pauseSchedulerAndActions];
	[image_ pauseSchedulerAndActions];
	if (nil != particle_)
	{
		[particle_ pauseSchedulerAndActions];
	}
}

- (void)Resume
{
	[self resumeSchedulerAndActions];
	[image_ resumeSchedulerAndActions];
	if (nil != particle_)
	{
		[particle_ resumeSchedulerAndActions];
	}
}

- (bool)IsMyFixture:(b2Fixture *)Fixture
{
	if (NULL == box2dBody_)
	{
		return false;
	}
	else
	{
		return Fixture == box2dFixture_;
	}
}

- (void)ItemFunctionTimeStop
{
	if (flagTimeStopValid_)
	{
		switch (state_)
		{
		case BOMB_STATE_MOVE:
			[self pauseSchedulerAndActions];
			[image_ pauseSchedulerAndActions];
			break;
		case BOMB_STATE_DESTROY: break;
		case BOMB_STATE_EXPLOSION: break;
		default:;
		}
	}
}

- (void)ItemFunctionTimeStopOver
{
	if (flagTimeStopValid_)
	{
		switch (state_)
		{
		case BOMB_STATE_MOVE:
			[self resumeSchedulerAndActions];
			[image_ resumeSchedulerAndActions];
			break;
		case BOMB_STATE_DESTROY: break;
		case BOMB_STATE_EXPLOSION: break;
		default:;
		}
	}
}

- (void)ActionAttack:(float)Time And:(CGPoint)EndPos
{
	CCSequence *_Seq;
	id _ActionMove;
	CCCallFuncN *_CallBack;

	if (BOMB_STATE_DESTROY == state_)
	{
		return;
	}

	state_ = BOMB_STATE_MOVE;
	[self StopAction];
	switch (type_)
	{
	case BOMB_TYPE_0:
	case BOMB_TYPE_1:
		_ActionMove = [action_move_in_pixel actionWithDuration:Time position:EndPos];
		_CallBack = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionMoveOver:)];
		_Seq = [CCSequence actions:_ActionMove, _CallBack, nil];
		[self runAction:_Seq];
		break;
	case BOMB_TYPE_2:
	case BOMB_TYPE_3:
	case BOMB_TYPE_4:
	case BOMB_TYPE_5:
		[self PlayAniFly];
		_ActionMove = [action_move_in_pixel actionWithDuration:Time position:EndPos];
		_CallBack = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionMoveOver:)];
		_Seq = [CCSequence actions:_ActionMove, _CallBack, nil];
		[self runAction:_Seq];
		break;
	case BOMB_TYPE_6:
		flagBombType6State_ = BOMB_TYPE_6_STATE_BIG;
		bombType6BigTime_ = Time * 0.3;
		bombType6SmallTime_ = Time * 0.7;
		bombType6LineWidth_ = 0;
		bombType6LineBigSegment_ = 4.0f / bombType6BigTime_;
		bombType6LineSmallSegment_ = 4.0f / (bombType6SmallTime_ * 2);
		bombType6EndPoition_ = ccpSub(EndPos, self.positionInPixels);
		image_.scaleY = -bombType6EndPoition_.y;
		image_.anchorPoint = ccp(0.5, 1.0);
		[self schedule:@selector(tickBombType6Over:) interval:Time];
		[self schedule:@selector(tickBombType6BigOver:) interval:bombType6BigTime_];
		break;
	default:;
	}
}

- (void)ActionDestroy
{
	if (BOMB_STATE_DESTROY == state_)
	{
		return;
	}

	state_ = BOMB_STATE_DESTROY;
	[self DestroyBody];
	[self StopAction];
	particle_ = [CCParticleSystemQuad particleWithFile:[NSString stringWithUTF8String:g_CfgGameBombDataTable[type_].particle_effect_explode]];
	[self addChild:particle_];
	[image_ runAction:[CCHide action]];
	[self runAction:tcCreateActionCallBack(self, 2, @selector(CallBackActionDestroyOver:))];

	/*effect
	*/
	EffectBombExplosion();
}

- (void)ActionExplosion
{
	if (BOMB_STATE_DESTROY == state_)
	{
		return;
	}

	state_ = BOMB_STATE_EXPLOSION;
	[self DestroyBody];
	[self StopAction];
	particle_ = [CCParticleSystemQuad particleWithFile:[NSString stringWithUTF8String:g_CfgGameBombDataTable[type_].particle_effect_explode]];
	[self addChild:particle_];
	[image_ runAction:[CCHide action]];
	[self runAction:tcCreateActionCallBack(self, 2, @selector(CallBackAniExplosionOver:))];

	/*effect
	*/
	EffectBombExplosion();
}

- (void)StopAction
{
	[self stopAllActions];
	[image_ stopAllActions];
	if (particle_ != nil)
	{
		[particle_ stopAllActions];
	}
}

- (void)PlayAniFly
{
	id _ActionFly;

	_ActionFly = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:uiCreateAnimationObject(&g_CfgGameBombDataTable[type_].ani_fly)]];
	[image_ runAction:_ActionFly];
}

- (void)CallBackActionMoveOver:(id)Sender
{
	CMgrGameMission::Instance()->EventEnemyAttackSuccess(self);
	[self ActionExplosion];
}

- (void)CallBackActionDestroyOver:(id)Sender
{
	[g_LayerGameObject RemoveBomb:self];
}

- (void)CallBackAniExplosionOver:(id)Sender
{
	[g_LayerGameObject RemoveBomb:self];
}

- (void)CallBackBombType6LineWidthBigOver:(id)Sender
{
	flagBombType6State_ = BOMB_TYPE_6_STATE_SMALL;
}

- (void)CallBackBombType6LineWidthSmallOver:(id)Sender
{
	[g_LayerGameObject RemoveBomb:self];
}

@end

@implementation SpriteGameSwirl

- (id)initSpriteGameSwirl:(int)Type
{
	NSString *_Path;

	if ((self = [super init]))
	{
		type_ = Type;

		[self schedule:@selector(tickLifeCycle:) interval:g_CfgGameSwirlDataTable[type_].life_cycle];
		_Path = [NSString stringWithUTF8String:g_CfgGameSwirlDataTable[type_].image_path];
		image_ = [[CCSprite alloc] initWithSpriteFrameName:_Path];
		[self addChild:image_];
		[image_ release];
		self.scale = 0.0f;
		[self PlayAni];
	}
	return self;
}

- (void)tickLifeCycle:(ccTime)Time
{
	[self unschedule:@selector(tickLifeCycle:)];
	[self unschedule:@selector(tickDestroyBridge:)];
	[self schedule:@selector(tickCheckHeartOver:)];
}

- (void)tickCheckHeartOver:(ccTime)Time
{
	if (heartList_.size() == 0)
	{
		[self ActionDisappear];
	}
}

- (void)tickDestroyBridge:(ccTime)Time
{
	sprite_game_heart *_Heart;

	if (g_SpriteGameBridge.point > 6)
	{
		_Heart = [[sprite_game_heart alloc] initSpriteGameHeart:6];
		[g_LayerGameObject AddHeart:_Heart];
		[_Heart ActionMoveToSwirl:self And:[g_SpriteGameBridge GetBridgeHeadPosition] And:self.positionInPixels];
		[g_SpriteGameBridge DecPoint:3];
		heartList_.push_back(_Heart);
	}
}

- (void)Pause
{
	[self pauseSchedulerAndActions];
	[image_ pauseSchedulerAndActions];
}

- (void)Resume
{
	[self resumeSchedulerAndActions];
	[image_ resumeSchedulerAndActions];
}

- (void)DetachmentHeart:(sprite_game_heart *)Heart
{
	heartList_.remove(Heart);
}

- (void)PlayAni
{
	id _Action;

	[image_ stopAllActions];
	_Action = [CCAnimate actionWithAnimation:uiCreateAnimationObject(&g_CfgGameSwirlDataTable[type_].ani)];
	[image_ runAction:[CCRepeatForever actionWithAction:_Action]];
}

- (void)ActionAppear
{
	CCSequence *_Seq;
	id _Action;
	CCCallFuncN *_CallBack;

	_Action = [CCScaleTo actionWithDuration:1.0f scale:1.0f];
	_CallBack = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionAppearOver:)];
	_Seq = [CCSequence actions:_Action, _CallBack, nil];
	[self runAction:_Seq];
}

- (void)ActionDisappear
{
	CCSequence *_Seq;
	id _Action;
	CCCallFuncN *_CallBack;

	_Action = [CCScaleTo actionWithDuration:1.0f scale:0.0f];
	_CallBack = [CCCallFuncN actionWithTarget:self selector:@selector(CallBackActionDisappearOver:)];
	_Seq = [CCSequence actions:_Action, _CallBack, nil];
	[self runAction:_Seq];
}

- (void)CallBackActionAppearOver:(id)Sender
{
	[self schedule:@selector(tickDestroyBridge:) interval:g_CfgGameSwirlDataTable[type_].eat_heart_time];
}

- (void)CallBackActionDisappearOver:(id)Sender
{
	[g_LayerGameObject RemoveSwirl:self];
}

@end